package com.example.emos.wx.service.impl;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.example.emos.wx.db.mapper.TbMeetingMapper;
import com.example.emos.wx.db.mapper.TbUserMapper;
import com.example.emos.wx.db.pojo.TbMeeting;
import com.example.emos.wx.exception.EmosException;
import com.example.emos.wx.service.MeetingService;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.crypto.hash.Hash;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * @ClassName MeetingServiceImpl
 * @Description TODO
 * @Author daoketa
 * @Version 1.0
 **/
@Service
@Slf4j
public class MeetingServiceImpl implements MeetingService {

    @Autowired
    private TbMeetingMapper meetingMapper;

    @Autowired
    private TbUserMapper userMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    @Value("${emos.receiveNotify}")
    private String receiveNotify;

    @Value("${workflow.url}")
    private String workflow;

    @Value("${emos.code}")
    private String code;

    /**
     * 添加会议
     * @author daoketa
     * @param
     *
     */
    @Override
    public void insertMeeting(TbMeeting meeting) {
        Integer rows = meetingMapper.insertMeeting(meeting);
        if (rows != 1){
            throw new EmosException("添加会议失败!");
        }
        /** 开启审批工作流 */
        Long creatorId = meeting.getCreatorId();
        String meetingType = meeting.getType() == 1 ? "线上会议" : "线下会议";
        startMeetingWorkflow(creatorId.intValue(), meeting.getUuid(), meeting.getTitle(), meeting.getDate(), meeting.getStart(), meetingType);
    }

    /**
     * 编辑会议
     * @author daoketa
     * @param
     */
    @Override
    public void updateMeeting(HashMap param){
        int id = (int) param.get("id");
        String title = param.get("title").toString();
        String date = param.get("date").toString();
        String start = param.get("start").toString();
        String instanceId = param.get("instanceId").toString();
        Byte type = (Byte) param.get("type");
        String meetingType = type == 1 ? "线上会议" : "线下会议";

        //查询修改前的会议记录
        HashMap oldMeeting = meetingMapper.searchMeetingById(id);
        String uuid = oldMeeting.get("uuid").toString();
        Integer creatorId = Integer.parseInt(oldMeeting.get("creatorId").toString());

        int row = meetingMapper.updateMeeting(param); //更新会议记录
        if (row != 1) {
            throw new EmosException("会议更新失败");
        }

        //会议更新成功之后，删除以前的工作流
        JSONObject json = new JSONObject();
        json.set("instanceId", instanceId);
        json.set("reason", "会议被修改");
        json.set("uuid",uuid);
        json.set("code",code);
        json.set("type",meetingType);
        String url = workflow+"/workflow/deleteProcessById";
        HttpResponse resp = HttpRequest.post(url).header("content-type", "application/json").body(json.toString()).execute();
        if (resp.getStatus() != 200) {
            log.error("删除工作流失败");
            throw new EmosException("删除工作流失败");
        }

        //创建新的工作流
        startMeetingWorkflow(creatorId, uuid, title, date, start, meetingType);
    }

    /**
     * 删除会议
     * @author daoketa
     * @param
     *
     */
    @Override
    public void deleteMeetingById(Integer id) {
        // 查询会议数据
        HashMap param = meetingMapper.searchMeetingById(id);

        // 会议开始前20分钟，不能删除会议
        DateTime date = DateUtil.parse(param.get("date") + " " + param.get("start"));
        DateTime now=DateUtil.date();
        if(now.isAfterOrEquals(date.offset(DateField.MINUTE,-20))){
            throw new EmosException("距离会议开始不足20分钟，不能删除会议");
        }

        // 删除会议
        Integer rows = meetingMapper.deleteMeetingById(id);
        if (rows != 1){
            throw new EmosException("删除会议失败");
        }

        // 删除工作流
        String instanceId = param.get("instanceId").toString();
        String uuid = param.get("uuid").toString();
        Byte type = Byte.parseByte(param.get("type").toString()) ;
        String meetingType = type == 1 ? "线上会议" : "线下会议";
        JSONObject json = new JSONObject();
        json.set("instanceId", instanceId);
        json.set("reason", "会议被修改");
        json.set("uuid",uuid);
        json.set("code",code);
        json.set("type", meetingType);
        String url = workflow+"/workflow/deleteProcessById";
        HttpResponse resp = HttpRequest.post(url).header("content-type", "application/json").body(json.toString()).execute();
        if (resp.getStatus() != 200) {
            log.error("删除工作流失败");
            throw new EmosException("删除工作流失败");
        }
    }

    /**
     * 开启审批工作流
     * @author daoketa
     * @param
     *
     */
    private void startMeetingWorkflow(Integer creatorId, String meetingUuid, String title, String date, String start, String meetingType){
        /** 查询创建者信息 */
        HashMap userInfo = userMapper.searchUserInfo(creatorId);

        /** 初始化请求参数 */
        JSONObject jsonObject = new JSONObject();
        jsonObject.set("url",receiveNotify);
        jsonObject.set("uuid", meetingUuid);
//        jsonObject.set("openId", userInfo.get("openId").toString());
        jsonObject.set("creatorId", creatorId);
        jsonObject.set("title", title);
        jsonObject.set("creatorName", userInfo.get("name").toString());

        jsonObject.set("code", code);
        jsonObject.set("date", date);
        jsonObject.set("start", start);
        jsonObject.set("meetingType", meetingType);
        String[] roles = userInfo.get("roles").toString().split("，");
        /** 不是总经理创建会议，需要审批 */
        if (!ArrayUtil.contains(roles,"总经理")){
            Integer deptManagerId = userMapper.searchDeptManagerId(creatorId);
            Boolean bool = meetingMapper.searchMeetingMembersInSameDept(meetingUuid);
            Integer gmId = userMapper.searchGmId();
            jsonObject.set("managerId",deptManagerId); // 部门经理 id
            jsonObject.set("gmId",gmId);    // 总经理 id
            jsonObject.set("sameDept",bool);    // 判断会议成员是否同一部门
        }
        /** 请求工作流接口，开启工作流 */
        String url = workflow+"/workflow/startMeetingProcess";
        HttpResponse response = HttpRequest.post(url)
                .header("Content-Type", "application/json")
                .body(jsonObject.toString()).execute();
        if (response.getStatus() == 200) {
            jsonObject = JSONUtil.parseObj(response.body());
            // 如果工作流创建成功，就更新会议状态
            String instanceId = jsonObject.getStr("instanceId");
            HashMap param = new HashMap();
            param.put("uuid", meetingUuid);
            param.put("instanceId", instanceId);
            int row = meetingMapper.updateMeetingInstanceId(param); //在会议记录中保存工作流实例的ID
            if (row != 1) {
                throw new EmosException("保存会议工作流实例ID失败");
            }
        }
    }

    /**
     * 根据id查询会议信息
     * @author daoketa
     * @param
     */
    @Override
    public HashMap searchMeetingById(Integer id){
        HashMap hashMap = meetingMapper.searchMeetingById(id);
        ArrayList<HashMap> members = meetingMapper.searchMeetingMembers(id);
        hashMap.put("members",members);
        return hashMap;
    }

    /**
     * 获取某个会议的房间号
     * @author daoketa
     * @param
     *
     */
    @Override
    public Long searchRoomIdByUUID(String uuid) {
        Object roomIdStr = redisTemplate.opsForValue().get(uuid);
        log.info(roomIdStr.toString());
        long roomId = Long.parseLong(roomIdStr.toString());
        return roomId;
    }

    @Override
    public List<String> searchUserMeetingInMonth(HashMap hashMap) {
        List<String> list = meetingMapper.searchUserMeetingInMonth(hashMap);
        return list;
    }

    /**
     * 分页查询会议信息
     * @author daoketa
     * @param
     */
    @Override
    public ArrayList<HashMap> searchMeetingByPage(HashMap hashMap) {
        ArrayList<HashMap> list = meetingMapper.searchMeetingByPage(hashMap);

        // 数据按日期分组
        ArrayList resultList = new ArrayList<>();
        JSONArray array = null;
        String date = null;
        HashMap resultMap = null;

        for (HashMap one : list) {
            String temp = one.get("date").toString();
            // 当日期不同，新建分组
            if (!temp.equals(date)){
                date = temp;
                resultMap = new HashMap();
                array = new JSONArray();
                resultMap.put("date", date);
                resultMap.put("list", array);
                resultList.add(resultMap);
            }
            array.put(one);
        }

        return resultList;
    }
}
